# !/usr/bin/env python
# -*- coding:utf-8 -*-
# author:ouyang time:2023/4/5
import json
import threading
import time
import socket
import base64
import os
import copy
import signal
from collections import deque


class RSUBroadcast(threading.Thread):
    """
    收集车辆的信息
    """
    def __init__(self):

        threading.Thread.__init__(self)

        """ 定义常量 """
        self.run_environment = 'pc'
        self.RSU_ID = 'RSU0001'
        self.RSU_Broadcast_IP = '10.0.0.255'
        self.PC_Broadcast_IP = '<broadcast>'
        self.RSU_COVER_PORT = 61121
        self.RSU_UDP_PORT = 1060
        self.HOST_IP = '127.0.0.1'

        """ 选择运行环境 """
        if self.run_environment == 'pc':
            self.rsu_connect_ip = self.HOST_IP
            self.broadcast_network = self.PC_Broadcast_IP

        """初始化UDP客户端"""
        self.udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.udp_client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        self.client_port = self.RSU_UDP_PORT
        self.broadcast_init()

        """socket连接状态、数据缓存"""
        self.connect_sta = 0     # 连接状态变为断开状态
        self.thread_run = 0      # 线程结束状
        self.time_stamp = 0
        self.broadcast_data = {}

    def broadcast_init(self):
        """
        用于发送广播信息，发送服务端地址，用于客户端建立连接
        :return:
        """

    def send_broadcast(self):
        """
        :return: 无
        """
        pre_send = json.dumps(self.broadcast_data)
        send = pre_send.encode('utf-8')
        self.udp_client.sendto(send, (self.broadcast_network, self.client_port))

    def structure_data(self):
        """
        :return: 构造好的json数据
        """
        self.broadcast_data.clear()
        self.broadcast_data['ID'] = self.RSU_ID
        self.broadcast_data['TIME_STAMP'] = self.time_stamp
        self.broadcast_data['IP'] = self.rsu_connect_ip
        self.broadcast_data['PORT'] = self.RSU_COVER_PORT

        print(self.broadcast_data)

    def run(self):
            self.udp_server_task()

    def udp_server_task(self):

        while True:
            try:
                self.update_info()
                self.structure_data()
                self.send_broadcast()
                time.sleep(1)

            except Exception as e:
                print(e)
                return 0

    def update_info(self):
        self.time_stamp = round(time.time(), 4)


class RSUListen(threading.Thread):
    """
    收集车辆的信息
    """

    def __init__(self):

        threading.Thread.__init__(self)

        """ 定义常量 """
        self.run_environment = 'pc'
        self.RSU_ID = 'RSU0001'
        self.RSU_Broadcast_IP = '10.0.0.255'
        self.PC_Broadcast_IP = '<broadcast>'
        self.RSU_COVER_PORT = 61121
        self.RSU_UDP_PORT = 1060
        self.HOST_IP = '127.0.0.1'

        """ 选择运行环境 """
        if self.run_environment == 'pc':
            self.rsu_connect_ip = self.HOST_IP
            self.broadcast_network = self.PC_Broadcast_IP

        """初始化TCP客户端"""
        self.rsu_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.rsu_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_port = self.RSU_COVER_PORT
        self.rsu_server.bind(('', self.server_port))

        """socket连接状态、数据缓存"""
        self.connect_sta = 0  # 连接状态变为断开状态
        self.thread_run = 0  # 线程结束状态
        self.time_stamp = 0
        self.connect_obj_buff = deque()
        self.connect_obj_set = set()

    def waite_for_car_connect(self):
        # 使socket处于监听状态，等待客户端的连接请求
        # 最多连接几个客户端
        self.rsu_server.listen(1)

        print("---------CAR Server start!---------")

        # 等待客户端连接连接，如果客户端连接，就会获取到客户端套接字连接和客户端地址
        conn, addr = self.rsu_server.accept()
        print("Success connect from ", addr)
        conn.send("ok".encode())  # 服务器连接需要得到密码确认
        data = conn.recv(4096)
        data = data.decode('utf-8')
        print(data)
        if data == 'ok':
            print("车辆连接成功！")
            return conn
        else:
            print("连接失败！")
            return 0

    def run(self):
        self.udp_server_task()

    def udp_server_task(self):

        while True:
            try:
                new_conn, address = self.waite_for_car_connect()
                if new_conn != 0:  # 如果都返回0,则表示建立连接异常
                    self.connect_obj_buff.append(new_conn)
                    self.connect_obj_set.add(new_conn)
            except Exception as e:
                print(e)
                return 0

    def get_conn_obj(self):

        return self.connect_obj_set


# if __name__ == '__main__':
#     rsu = RSUBroadcast()
#     print("到这里了1")
#     rsu.run()
#     print("到这里了2")
